package cn.itcast.web.controller.system;

import cn.itcast.domain.system.Dept;
import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.Role;
import cn.itcast.service.system.DeptService;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.RoleService;
import cn.itcast.web.controller.BaseController;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色控制器
 */
@Controller
@RequestMapping("/system/role")
public class RoleController extends BaseController{

    @Autowired
    private RoleService roleService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private ModuleService moduleService;


    /**
     * 分页查询
     *   1）URL：http://localhost:8080/system/role/list.do
     *   2）参数：pageNum=1&pageSize=5
     *   3)返回： /WEB-INF/pages/system/role/role-list.jsp
     */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer pageNum,
                       @RequestParam(defaultValue = "5") Integer pageSize){
        //当前登录企业的ID
        String companyId = getLoginCompanyId();

        //1.查询角色数据
        PageInfo pageInfo = roleService.findByPage(pageNum,pageSize,companyId);

        //2.存入request域
        request.setAttribute("pageInfo",pageInfo);

        //3.返回页面
        return "system/role/role-list";
    }

    /**
     * 进入添加页面
     *  1）URL：http://localhost:8080/system/role/toAdd.do
     *  2）参数：无
     *  3）返回：/WEB-INF/pages/system/role/role-add.jsp
     */
    @RequestMapping("/toAdd")
    public String toAdd(){
        return "system/role/role-add";
    }

    /**
     * 保存数据（添加/修改）
     *   1）URL：http://localhost:8080/system/role/edit.do
     *   2）参数：角色表单数据
     *   3）返回：重定向回到列表
     */
    @RequestMapping("/edit")
    public String edit(Role role){
        //获取登录企业信息
        String companyId = getLoginCompanyId();
        String companyName = getLoginCompanyName();

        role.setCompanyId(companyId);
        role.setCompanyName(companyName);

        //判断是否有ID
        if(StringUtils.isEmpty(role.getId())){
            //添加
            roleService.save(role);
        }else{
            //修改
            roleService.update(role);
        }

        return "redirect:/system/role/list.do";
    }

    /**
     * 进入修改页面
     *  1）URL：http://localhost:8080/system/role/toUpdate.do
     *  2)参数：id=1f35c554-3777-419b-b607-f88473068edb
     *  3)返回：/WEB-INF/pages/system/role/role-update.jsp
     */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id){
        String companyId = getLoginCompanyId();

        //1.根据id查询角色
        Role role = roleService.findById(id);
        //2.存入request域
        request.setAttribute("role",role);

        return "system/role/role-update";
    }

    /**
     * 删除角色
     *  1）URL：http://localhost:8080/system/role/delete.do
     *  2）参数：id=1
     *  3）返回：{"flag":true/false,"errorMsg":"xxxxx"}
     */
    @RequestMapping("/delete")
    @ResponseBody //把Java对象转换为Json字符串
    public Map<String,Object> delete(String id){
        return null;
    }


    /**
     * 进入角色分配权限页面
     *  1）URL：http://localhost:8080/system/role/roleModule.do
     *  2）参数：roleid=4028a1c34ec2e5c8014ec2ebf8430001
     *  3）返回：/WEB-INF/pages/system/role/role-module.jsp
     */
    @RequestMapping("/roleModule")
    public String roleModule(String roleid){
        //1.查询当前角色
        Role role = roleService.findById(roleid);
        request.setAttribute("role",role);
        return "system/role/role-module";
    }

    /**
     * 加载模块树状结构
     *  1）URL： http://localhost:8080/system/role/getZtreeNodes.do
     *  2）参数： roleid=1
     *  3）返回： [ {id:1,name:'',pId:1,open:true,checked:true},{} ]
     *
     */
    @RequestMapping("/getZtreeNodes")
    @ResponseBody // 转换为json字符串
    public List<Map<String,Object>> getZtreeNodes(String roleid){
        //List<Map<String,Object>>： 封装树的所有节点数据
        List<Map<String,Object>> list = new ArrayList<>();

        //1.查询所有模块列表
        List<Module> moduleList = moduleService.findAll();

        //2.查询当前角色分配过的模块列表
        List<Module> roleModuleList = moduleService.findRoleModuleByRoleId(roleid);

        //3.把模块数据存入到Map中
        if(moduleList!=null && moduleList.size()>0){
            for(Module module:moduleList){

                //使用一个Map封装树的一个节点数据
                Map<String,Object> map = new HashMap<>();

                //id
                map.put("id",module.getId());
                //name
                map.put("name",module.getName());
                //pId
                map.put("pId",module.getParentId());
                //open
                map.put("open",true);

                //让哪些分配过角色的模块，添加上复选框勾选
                /**
                 * 实现一：
                for(Module module2:roleModuleList){
                    if(module.getId().equals(module2.getId())){
                        map.put("checked",true);
                    }
                }
                */

                //实现二：
                /**
                 * contains: 判断一个集合中是否包含某个指定对象
                 *   1）情况一： 集合中的某个对象 和 指定对象的内存地址一样的，两个对象必然是相同的，返回true
                 *   2）情况二： 集合中的所有的对象 和 指定对象的内存地址不一样的，默认情况下返回false
                 *         如果在覆盖了对象的hashCode和equals方法的时候，那么contains方法不再是判断内存地址，
                 *          而是根据hashCode和equals方法的结果判断对象是否一样！
                 *
                 *          hashCode和equals方法判断对象是否一致的过程：
                 *            1）调用对象的hashCode方法
                 *                  如果两个对象的hashCode返回值不一样，直接判定两个对象不一致！
                 *                  如果两个对象的hashCode返回值一样，继续调用equals方法
                 *            2）调用对象的equals方法
                 *                  如果equals方法返回false，直接判定两个对象不一致！
                 *                  如果equals方法返回true，判断两个对象一致的！
                 *
                 *
                 *          问题：如果让两个对象是一致的，你要怎么做？
                 *              1） 必须覆盖hashCode方法，且返回 我们用来判断对象一致的属性的hashCode值（如：例如我们认为id一样就相等，那么应该返回id的hashCode）
                 *              2） 必须equals方法，使用我们认为对象一致的属性来作为判断的条件
                 *                      例如
                 *                          public boolean equals(Object obj){
                 *                              Module module = (Module)obj;
                 *
                 *                              if(this.id.equals(module.id)){
                 *                                  return true;
                 *                              }else{
                 *                                  return false;
                 *                              }
                 *                          }
                 *
                 */

                if(roleModuleList.contains(module)){
                    map.put("checked",true);
                }


                //4.把Map放入List中
                list.add(map);
            }
        }

        return list;
    }

    /**
     * 保存角色和模块的关系
     *  1）URL：http://localhost:8080/system/role/updateRoleModule.do
     *  2）参数：roleid=1&moduleIds=1,2,3
     *  3）返回：重定向到列表
     */
    @RequestMapping("/updateRoleModule")
    public String updateRoleModule(String roleid,String moduleIds){

        //调用service方法
        roleService.updateRoleModule(roleid,moduleIds);

        return "redirect:/system/role/list.do";
    }
}
